/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.geotools.tutorial;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import java.awt.geom.Point2D;

/**
 *
 * @author oleg
 */
public class SomeMath {
/**
     * Возвращает точку-проекцию на ближайшую линию на карте, подсвечивает
     * выделеную полилинию.
     * @param x
     * @param y
     * @return
     */
    static public Point2D.Double getClosestPositionOnTrack(double x, double y, Geometry geom) {
        double distance = 999999999;
        Point2D.Double pointOnLine = new Point2D.Double();
        Coordinate[] line = geom.getCoordinates();

        for (int i = 0; i < line.length - 1; i++) {

            double x0 = line[i].x;
            double y0 = line[i].y;
            double x1 = line[i + 1].x;
            double y1 = line[i + 1].y;
            double x_min, y_min, x_max, y_max;
            if (x0 <= x1) {
                x_min = x0;
                x_max = x1;
            } else {
                x_min = x1;
                x_max = x0;
            }
            if (y0 <= y1) {
                y_min = y0;
                y_max = y1;
            } else {
                y_min = y1;
                y_max = y0;
            }
            if ((x <= x_max) && (x >= x_min) && (y <= y_max) && (y >= y_min)) {
                double a = y0 - y1;
                double b = x1 - x0;
                double c = x0 * y1 - x1 * y0;
                double dist = Math.abs((x * a + y * b + c) / Math.pow(a * a + b * b, 0.5));



                if ((dist < distance) && (Point2D.distance(x, y, x1, y1) >= dist) && (Point2D.distance(x, y, x0, y0) >= dist)) {
                    distance = dist;

                    double d = a * y - b * x;
                    double det = -a * a - b * b;
                    double det1 = a * c + b * d;
                    double det2 = -a * d + b * c;

                    pointOnLine.setLocation(det1 / det, det2 / det);
                }
            }
        }


        return pointOnLine;
    }
}
